#ifndef _SYS_TYPE_H_
#define _SYS_TYPE_H_

#include "FanObj.h"
#include "SysTypes.h"

#define TYPE_VTABLE(self)   ((TypeVTable*)((FanObj*)self)->vtable)


extern Type*    Type_classType;
extern VTable*  Type_classVTable;


/* [sys::Type] Attributes */
struct Type
{
  FanObj        super;
  Int           depth;
  Type**        hierarchy;
};


/* [sys::Type] Virtual-table */
typedef struct TypeVTable
{
  FanObjVTable  super;
} TypeVTable;


/* [sys::Type] Methods and fields */
Str*            Type_toStr(Obj self);
Type*           Type_of(Obj obj);
Type*           Type_find_1(Str* qname);
Type*           Type_find(Str* qname, Bool checked);
Pod*            Type_pod(Type* self);
Str*            Type_name(Type* self);
Str*            Type_qname(Type* self);
Str*            Type_signature(Type* self);
Type*           Type_base(Type* self);
List*           Type_mixins(Type* self);
List*           Type_inheritance(Type* self);
Bool            Type_fits(Type* self, Type* t);
Bool            Type_isVal(Type* self);
Bool            Type_isNullable(Type* self);
Type*           Type_toNullable(Type* self);
Type*           Type_toNonNullable(Type* self);
Bool            Type_isGeneric(Type* self);
Map*            Type_params(Type* self);
Type*           Type_parameterize(Type* self, Map* params);
Type*           Type_toListOf(Type* self);
List*           Type_emptyList(Type* self);
Bool            Type_isAbstract(Type* self);
Bool            Type_isClass(Type* self);
Bool            Type_isConst(Type* self);
Bool            Type_isEnum(Type* self);
Bool            Type_isFacet(Type* self);
Bool            Type_isFinal(Type* self);
Bool            Type_isInternal(Type* self);
Bool            Type_isMixin(Type* self);
Bool            Type_isPublic(Type* self);
Bool            Type_isSynthetic(Type* self);
List*           Type_fields(Type* self);
List*           Type_methods(Type* self);
List*           Type_slots(Type* self);
Field*          Type_field_1(Type* self, Str* name);
Field*          Type_field(Type* self, Str* name, Bool checked);
Method*         Type_method_1(Type* self, Str* name);
Method*         Type_method(Type* self, Str* name, Bool checked);
Slot*           Type_slot_1(Type* self, Str* name);
Slot*           Type_slot(Type* self, Str* name, Bool checked);
Obj             Type_make_0(Type* self);
Obj             Type_make(Type* self, List* args);
List*           Type_facets(Type* self);
Facet*          Type_facet_1(Type* self, Type* type);
Facet*          Type_facet(Type* self, Type* type, Bool checked);
Bool            Type_hasFacet(Type* self, Type* type);
Str*            Type_doc(Type* self);
Str*            Type_toLocale(Type* self);


/* [sys::Type] Extra methods */
Type*           Type_new(const char* name, Type* base, VTable* vtable, size_t instanceSize, size_t vtableSize);
void            Type_registerCtorImplementation(Type* self, const char* methodName, void* ctorImpl, Int numParams);
void            Type_registerMethodImplementation(Type* self, const char* methodName, void* methodImpl, Int numParams);
void            Type_registerFieldImplementation(Type* self, const char* fieldName, void* getterImpl, void* setterImpl);


/* [sys::Type] Type-system functions */
Type*           Type_initType(void);
VTable*         Type_initVTable(void);
void            Type_initStatic(void);


#endif
